home *** CD-ROM | disk | FTP | other *** search
- // Gmail Manager
- // By Todd Long <longfocus@gmail.com>
- // http://www.longfocus.com/firefox/gmanager/
-
- const GM_CC = Components.classes;
- const GM_CI = Components.interfaces;
-
- const GM_NOTIFY_ACCOUNT_STATE_CONNECTING = "gm-account-state-connecting";
- const GM_NOTIFY_ACCOUNT_STATE_LOGGED_OUT = "gm-account-state-logged-out";
- const GM_NOTIFY_ACCOUNT_STATE_LOGGED_OUT_NO_PASSWORD = "gm-account-state-logged-out-no-password";
- const GM_NOTIFY_ACCOUNT_STATE_LOGGED_IN_NO_MAIL = "gm-account-state-logged-in-no-mail";
- const GM_NOTIFY_ACCOUNT_STATE_LOGGED_IN_NEW_MAIL = "gm-account-state-logged-in-new-mail";
- const GM_NOTIFY_ACCOUNT_STATE_ERROR_PASSWORD = "gm-account-state-error-password";
- const GM_NOTIFY_ACCOUNT_STATE_ERROR_CAPTCHA = "gm-account-state-error-captcha";
- const GM_NOTIFY_ACCOUNT_STATE_ERROR_NETWORK = "gm-account-state-error-network";
- const GM_NOTIFY_ACCOUNT_STATE_ERROR_SERVER = "gm-account-state-error-server";
- const GM_NOTIFY_ACCOUNT_STATE_ERROR_TIMEOUT = "gm-account-state-error-timeout";
-
- function gmServiceGmail()
- {
- this._console = GM_CC['@mozilla.org/consoleservice;1'].getService(GM_CI.nsIConsoleService);
- this._observer = GM_CC["@mozilla.org/observer-service;1"].getService(GM_CI.nsIObserverService);
- this._cookies = GM_CC["@longfocus.com/gmanager/cookies;1"].getService(GM_CI.gmICookies);
- }
-
- gmServiceGmail.prototype = {
- _loggedIn: false,
- _status: GM_NOTIFY_ACCOUNT_STATE_LOGGED_OUT,
- _inboxUnread: 0,
- _savedDrafts: 0,
- _spamUnread: 0,
- _labels: null,
- _snippets: null,
- _spaceUsed: "0 MB",
- _percentUsed: "0%",
- _totalSpace: "0 MB",
- _timer: null,
- _interval: 0,
- _connectionPhase: 0,
- _isHosted: false,
- _isChecking: false,
- _cookieData: null,
-
- get loggedIn() { return this._loggedIn; },
- get status() { return this._status; },
- get inboxUnread() { return this._inboxUnread; },
- get savedDrafts() { return this._savedDrafts; },
- get spamUnread() { return this._spamUnread; },
- get spaceUsed() { return this._spaceUsed; },
- get percentUsed() { return this._percentUsed; },
- get totalSpace() { return this._totalSpace; },
-
- getLabels: function(aCount)
- {
- if (this._labels == null)
- this._labels = new Array();
- aCount.value = this._labels.length;
- return this._labels;
- },
-
- getSnippets: function(aCount)
- {
- if (this._snippets == null)
- this._snippets = new Array();
- aCount.value = this._snippets.length;
- return this._snippets;
- },
-
- login: function()
- {
- // Check for password
- if (this.password == null || this.password == "")
- {
- this._setStatus(GM_NOTIFY_ACCOUNT_STATE_LOGGED_OUT_NO_PASSWORD);
- }
- else if (!this._isChecking)
- {
- var url = null;
- var data = null;
-
- // Initialize login
- this._loggedIn = false;
- this._connectionPhase = 0;
- this._setChecking(true);
-
- try {
- this._timer = GM_CC["@mozilla.org/timer;1"].createInstance(GM_CI.nsITimer);
- this._timer.initWithCallback(this, 30000, this._timer.TYPE_ONE_SHOT);
- } catch(e) {}
-
- if (this.email.indexOf("@gmail.com") > -1 || this.email.indexOf("@googlemail.com") > -1 || this.email.indexOf("@") == -1)
- {
- this._isHosted = false;
-
- url = "https://www.google.com/accounts/ServiceLoginAuth";
- data = "ltmpl=wsad<mplcache=2" +
- "&continue=https://mail.google.com/mail/?&service=mail&rm=false<mpl=wsad" +
- "&Email=" + encodeURIComponent(this.email) +
- "&Passwd=" + encodeURIComponent(this.password) +
- "&null=Sign+in";
- }
- else
- {
- this._isHosted = true;
-
- var username = this.email.split("@")[0];
- var domain = this.email.split("@")[1];
-
- url = "https://www.google.com/a/" + domain + "/LoginAction";
- data = "at=null&continue=https://mail.google.com/hosted/" + domain + "/&service=mail" +
- "&userName=" + encodeURIComponent(username) +
- "&password=" + encodeURIComponent(this.password);
- }
-
- // Send request
- this._serverRequest(url, data);
- }
- },
-
- logout: function()
- {
- this._defaults();
- this._setChecking(false);
- this._setStatus(GM_NOTIFY_ACCOUNT_STATE_LOGGED_OUT);
-
- if (this._timer) {
- this._timer.cancel();
- this._timer = null;
- }
- },
-
- check: function()
- {
- if (!this._isChecking)
- {
- // Initialize login
- this._connectionPhase = 1;
- this._setChecking(true);
-
- try {
- this._timer = GM_CC["@mozilla.org/timer;1"].createInstance(GM_CI.nsITimer);
- this._timer.initWithCallback(this, 30000, this._timer.TYPE_ONE_SHOT);
- } catch(e) {}
-
- // Send request
- this._serverRequest(this._getPhaseURL(), null);
- }
- },
-
- setTimer: function(aInterval)
- {
- if (this._timer) {
- this._timer.cancel();
- this._timer = null;
- }
-
- if (aInterval > 0) {
- try {
- this._interval = aInterval;
- this._timer = GM_CC["@mozilla.org/timer;1"].createInstance(GM_CI.nsITimer);
- this._timer.initWithCallback(this, aInterval * 60000, this._timer.TYPE_ONE_SHOT);
- } catch(e) {}
- }
- },
-
- notify: function(aTimer)
- {
- if (this._isChecking)
- {
- // Sets the timeout error
- this._setChecking(false);
- this._setStatus(GM_NOTIFY_ACCOUNT_STATE_ERROR_TIMEOUT);
-
- // Retry login in 30 seconds
- this.setTimer(0.3);
- }
- else
- this.check();
- },
-
- resetUnread: function()
- {
- // Reset account info
- this._inboxUnread = 0;
- this._savedDrafts = 0;
- this._spamUnread = 0;
- this._snippets = null;
-
- // Reset timer so info doesn't update
- this.setTimer(this._interval);
- },
-
- _setStatus: function(aStatus)
- {
- this._status = aStatus;
- this._observer.notifyObservers(null, this.email, aStatus);
- },
-
- _setChecking: function(aChecking)
- {
- if (aChecking)
- {
- // Load Google cookies
- this._cookies.loadSession("google.com");
-
- // Set status connecting
- this._setStatus(GM_NOTIFY_ACCOUNT_STATE_CONNECTING);
-
- try {
- // Adds the HTTP observers
- this._observer.addObserver(this, "http-on-modify-request", false);
- this._observer.addObserver(this, "http-on-examine-response", false);
- } catch(e) {}
- }
- else
- {
- // Restore Google cookies
- this._cookies.restoreSession("google.com");
-
- try {
- // Removes the HTTP observers
- this._observer.removeObserver(this, "http-on-modify-request");
- this._observer.removeObserver(this, "http-on-examine-response");
- } catch(e) {}
- }
-
- // Set checking
- this._isChecking = aChecking;
- },
-
- _defaults: function()
- {
- // Reset password
- if (!this.remember)
- this.password = null;
-
- // Account details
- this._loggedIn = false;
- this._inboxUnread = 0;
- this._savedDrafts = 0;
- this._spamUnread = 0;
- this._labels = null;
- this._snippets = null;
- this._spaceUsed = "0 MB";
- this._percentUsed = "0%";
- this._totalSpace = "0 MB";
-
- // Login help
- this._timer = null;
- this._interval = 0;
- this._connectionPhase = 0;
- this._isHosted = false;
- this._isChecking = false;
- this._cookieData = null;
- },
-
- _error: function(aError)
- {
- this._defaults();
- this._setChecking(false);
- this._setStatus(aError);
- },
-
- _getPhaseURL: function()
- {
- var url = null;
- var search = (this._connectionPhase == 1 ? "" : "?search=inbox&view=tl&start=0&init=1")
-
- if (!this._isHosted)
- url = "https://mail.google.com/mail/";
- else
- {
- var domain = this.email.split("@")[1];
- url = "https://mail.google.com/hosted/" + domain + "/";
- }
-
- return (url + search);
- },
-
- _serverRequest: function(aURL, aData)
- {
- var ioService = GM_CC["@mozilla.org/network/io-service;1"].createInstance(GM_CI.nsIIOService);
- var uri = ioService.newURI(aURL, "gmanager/" + this.email + "/", null);
- var channel = ioService.newChannelFromURI(uri);
-
- if (aData != null)
- {
- var uploadStream = GM_CC["@mozilla.org/io/string-input-stream;1"].createInstance(GM_CI.nsIStringInputStream);
- uploadStream.setData(aData, aData.length);
-
- var uploadChannel = channel.QueryInterface(GM_CI.nsIUploadChannel);
- uploadChannel.setUploadStream(uploadStream, "application/x-www-form-urlencoded", -1);
-
- channel.QueryInterface(GM_CI.nsIHttpChannel).requestMethod = "POST";
- }
-
- channel.asyncOpen(new this.observer(this), null);
- },
-
- observe: function(aSubject, aTopic, aData)
- {
- var httpChannel = aSubject.QueryInterface(GM_CI.nsIHttpChannel);
- var isGood = (httpChannel.originalURI.originCharset.indexOf("gmanager/" + this.email + "/") > -1);
-
- if (aTopic == "http-on-modify-request" && isGood)
- {
- var cookie = (this._cookieData != null ? this._cookieData : "");
-
- // Clears the Cookie data
- httpChannel.setRequestHeader("Cookie", "", false);
-
- for (var name in this._cookieData)
- httpChannel.setRequestHeader("Cookie", this._cookieData[name], true);
- }
- else if (aTopic == "http-on-examine-response" && isGood)
- {
- var cookies = null;
-
- try {
- cookies = httpChannel.getResponseHeader("Set-Cookie").split("\n");
- } catch(e) {}
-
- if (cookies != null)
- {
- if (this._cookieData == null)
- this._cookieData = new Object();
-
- for (var i = 0; i < cookies.length; i++)
- {
- var cookieValue = (cookies[i].split(";"))[0];
- var cookieName = (cookieValue.split("="))[0];
-
- if (cookieName.indexOf("ID") > -1 || cookieName.indexOf("GX") > -1)
- this._cookieData[cookieName] = cookieValue;
- }
- }
-
- // Clears the Set-Cookie header (Firefox 2.0)
- httpChannel.setResponseHeader("Set-Cookie", "", false);
- }
- },
-
- callback: function(aData, aRequest)
- {
- // Get the http channel containing our data
- var httpChannel = aRequest.QueryInterface(GM_CI.nsIHttpChannel);
-
- var network = true;
- var status = null;
- var statusText = null;
-
- try {
- // Get HTTP response
- status = httpChannel.responseStatus;
- statusText = httpChannel.responseStatusText;
- } catch (e) {
- network = false;
- }
-
- /*
- this._console.logStringMessage(this.email);
- this._console.logStringMessage(aData);
- this._console.logStringMessage(status + " - " + statusText)
- this._console.logStringMessage(network);
- this._console.logStringMessage("---");
- */
-
- if (!network) // Network was disconnected
- {
- // Sets the network error
- this._setChecking(false);
- this._setStatus(GM_NOTIFY_ACCOUNT_STATE_ERROR_NETWORK);
-
- // Retry login
- this.setTimer(0.3);
-
- return;
- }
- else if (status == null || status != 200) // Status wasn't good
- {
- // Check status
- if (status >= 500)
- this.check(); // Server error, try again
- else
- this._error(GM_NOTIFY_ACCOUNT_STATE_ERROR_SERVER);
-
- return;
- }
- else if (aData.indexOf("Welcome to Gmail") > -1)
- {
- // Sets the account error
- if (aData.indexOf("Username and password do not match") > -1)
- {
- // Reset the password
- this._password = null;
-
- // Sets error for incorrect password
- this._error(GM_NOTIFY_ACCOUNT_STATE_ERROR_PASSWORD);
- }
- else // Sets error for captcha required
- this._error(GM_NOTIFY_ACCOUNT_STATE_ERROR_CAPTCHA);
-
- return;
- }
- else if (aData.indexOf("Server error") > -1)
- {
- // Reset the password
- this._password = null;
-
- // Sets error for incorrect password
- this._error(GM_NOTIFY_ACCOUNT_STATE_ERROR_PASSWORD);
-
- return;
- }
-
- // Eveything looks good =)
- switch (++this._connectionPhase)
- {
- case 1:
- case 2:
- {
- // Send request
- this._serverRequest(this._getPhaseURL(), null);
- break;
- }
- case 3:
- {
- var newMail = false;
-
- // Resets the timer
- this.setTimer(this._interval);
-
- try {
- // Quota ["qu","68 MB","2610 MB","3%","#006633"]
- var myMatches = aData.match(/\["qu",.*\]/);
- var myValues = eval(myMatches[0]);
-
- this._spaceUsed = myValues[1] + (myValues[1].indexOf("MB") == -1 ? " MB" : "");
- this._totalSpace = myValues[2] + (myValues[2].indexOf("MB") == -1 ? " MB" : "");
- this._percentUsed = myValues[3] + (myValues[3].indexOf("%") == -1 ? "%" : "");
- } catch(e) {}
-
- try {
- // method 1 = ["ds",1,0,0,1,0,0,0] inbox, drafts, spam
- // method 2 = ["ds",[["inbox",0],["drafts",0],["spam",0]]]
- var myMatches = null;
- var isNew = aData.match(/\["ds",\[\[/);
-
- if (isNew)
- myMatches = aData.match(/\["ds",.*\n(.*]\n)+\]/);
- else
- myMatches = aData.match(/\["ds",.*\]/);
-
- var myValues = eval(myMatches[0]);
- var tempInbox = (isNew) ? myValues[1][0][1] : myValues[1];
-
- // Checks for new mail
- newMail = (tempInbox > this._inboxUnread);
-
- this._inboxUnread = tempInbox;
- this._savedDrafts = (isNew) ? myValues[1][1][1] : myValues[4];
- this._spamUnread = (isNew) ? myValues[1][2][1] : myValues[6];
- } catch(e) {}
-
- try {
- // Labels ["ct",[["label1",0],["label2",0]]]
- var myMatches = aData.match(/\["ct",.*\n(.*]\n)+\]/gm);
- var myValues = eval(eval(myMatches[0])[1]);
-
- // Clear the labels
- this._labels = new Array();
-
- for (var i = 0; i < myValues.length; i++)
- {
- var label = new gmServiceGmailLabel();
-
- // Set label
- label.name = myValues[i][0];
- label.unread = myValues[i][1];
-
- // Add the label
- this._labels.push(label);
- }
- } catch(e) {}
-
- try {
- // New Mail Snippets
- var myMatches = aData.match(/\["t",.*\n(.*]\n)+\]/gm);
- var myValues = eval(myMatches[0]);
-
- // Clear the snippets
- this._snippets = new Array();
-
- for (var j = 0; j < myMatches.length; j++)
- {
- var myValues = eval(myMatches[j]);
-
- for (var i = 1; i < myValues.length; i++)
- {
- var mySnippet = myValues[i];
- var snippet = new gmServiceGmailSnippet();
-
- if (mySnippet[1] == "1")
- {
- // Set snippet
- snippet.id = mySnippet[0];
- snippet.time = this._stripHtml(mySnippet[3]);
- snippet.sender = this._stripHtml(mySnippet[4]);
- snippet.subject = this._replaceHtmlCodes(this._stripHtml(mySnippet[6]));
- snippet.msg = this._replaceHtmlCodes(this._stripHtml(mySnippet[7]));
- snippet.labels = mySnippet[8];
- snippet.files = mySnippet[9]; // Separated by commas
- snippet.date = mySnippet[12];
-
- // Add the snippet
- this._snippets.push(snippet);
- }
- }
- }
- } catch(e) {}
-
- this._loggedIn = true;
- this._setChecking(false);
-
- if (newMail)
- this._setStatus(GM_NOTIFY_ACCOUNT_STATE_LOGGED_IN_NEW_MAIL);
- else
- this._setStatus(GM_NOTIFY_ACCOUNT_STATE_LOGGED_IN_NO_MAIL);
-
- break;
- }
- }
- },
-
- _stripHtml: function(aString)
- {
- return aString.replace(/(<([^>]+)>)/ig, "");
- },
-
- _replaceHtmlCodes: function(aString)
- {
- var htmlCodes = new Array(
- [">", ">"], ["<", "<"], ["'", "'"], [""", "\""],
- ["&", "&"], ["˜", "~"], ["™", "?"], ["©", "?"],
- ["®", "?"], ["…", ""] );
-
- for (var i = 0; i < htmlCodes.length; i++) {
- var re = new RegExp(htmlCodes[i][0], "g");
- aString = aString.replace(re, htmlCodes[i][1]);
- }
-
- return aString;
- },
-
- observer: function(aThis)
- {
- return ({
- _myData: "",
-
- onStartRequest: function(aRequest, aContext) {
- this._myData = "";
- },
-
- onStopRequest: function(aRequest, aContext, aStatus) {
- aThis.callback(this._myData, aRequest);
- },
-
- onDataAvailable: function(aRequest, aContext, aStream, aSourceOffset, aLength) {
- var scriptableInputStream = GM_CC["@mozilla.org/scriptableinputstream;1"].createInstance(GM_CI.nsIScriptableInputStream);
- scriptableInputStream.init(aStream);
- this._myData += scriptableInputStream.read(aLength);
- }});
- },
-
- QueryInterface: function(iid)
- {
- if (!iid.equals(GM_CI.gmIServiceGmail) &&
- !iid.equals(GM_CI.nsISupports))
- throw Components.results.NS_ERROR_NO_INTERFACE;
- return this;
- }
- }
-
- function gmServiceGmailLabel() {}
- gmServiceGmailLabel.prototype = {
- _name: null,
- _unread: null,
-
- get name() { return this._name; },
- get unread() { return this._unread; },
-
- set name(aName) { this._name = aName; },
- set unread(aUnread) { this._unread = aUnread; }
- }
-
- function gmServiceGmailSnippet() {}
- gmServiceGmailSnippet.prototype = {
- _id: null,
- _time: null,
- _sender: null,
- _subject: null,
- _msg: null,
- _labels: null,
- _files: null,
- _date: null,
-
- get id() { return this._id; },
- get time() { return this._time; },
- get sender() { return this._sender; },
- get subject() { return this._subject; },
- get msg() { return this._msg; },
- get labels() { return this._labels; },
- get files() { return this._files; },
- get date() { return this._date; },
-
- set id(aId) { this._id = aId; },
- set time(aTime) { this._time = aTime; },
- set sender(aSender) { this._sender = aSender; },
- set subject(aSubject) { this._subject = aSubject; },
- set msg(aMsg) { this._msg = aMsg; },
- set labels(aLabels) { this._labels = aLabels; },
- set files(aFiles) { this._files = aFiles; },
- set date(aDate) { this._date = aDate; }
- }
-
- var myModule = {
- firstTime: true,
-
- myCID: Components.ID("{b07df9d0-f7dd-11da-974d-0800200c9a66}"),
- myDesc: "Service for Gmail accounts",
- myProgID: "@longfocus.com/gmanager/service/gmail;1",
- myFactory: {
- createInstance: function (outer, iid) {
- if (outer != null)
- throw Components.results.NS_ERROR_NO_AGGREGATION;
-
- return (new gmServiceGmail()).QueryInterface(iid);
- }
- },
-
- registerSelf: function (compMgr, fileSpec, location, type)
- {
- if (this.firstTime) {
- this.firstTime = false;
- throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
- }
-
- compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
- compMgr.registerFactoryLocation(this.myCID, this.myDesc, this.myProgID, fileSpec, location, type);
- },
-
- getClassObject: function (compMgr, cid, iid)
- {
- if (!cid.equals(this.myCID))
- throw Components.results.NS_ERROR_NO_INTERFACE;
-
- if (!iid.equals(Components.interfaces.nsIFactory))
- throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-
- return this.myFactory;
- },
-
- canUnload: function(compMgr) { return true; }
- };
-
- function NSGetModule(compMgr, fileSpec) { return myModule; }